#!/usr/bin/env python
# -*- encoding=utf-8 -*-
'''
Created on 2017/12/28

@author: peulerosci
'''

import logging
import logging.config
import xml.etree.ElementTree as ET
from subprocess import *
import os, re, sys, datetime
reload(sys)
sys.setdefaultencoding('utf8')

if not os.path.isdir("log"):
    os.mkdir("log")
logging.config.fileConfig("logger.conf")
logger = logging.getLogger("copy_jenkins")

BRANCH = os.getenv('GERRIT_BRANCH')
REPO_DIR = '/usr1/jenkins/EulerOS_' + BRANCH
PROJECT = os.getenv('GERRIT_PROJECT')

error_msg = '''
Please check you changelog, must be:
* Week Mon Date Year Author<euleros@huawei.com> - 1.0-1
- Type:security etc.
- ID:CVE-2007-3568
- SUG:restart etc.
- DESC:Describe the problem in detail

for detail: http://plm-pia.huawei.com/Windchill/DBOX/docdetail/pageinfo.jsp?oid=VR:wt.doc.WTDocument:11587660775
'''


def shell_cmd(s_cmd_line, inmsg=None):
    p = Popen(s_cmd_line, stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
    if inmsg:
        p.stdin.write(inmsg)
    out, err = p.communicate()
    return p.returncode, out, err


def get_project_path():
    default_xml = REPO_DIR + '/.repo/manifest.xml'
    with open(default_xml, 'r') as myfile:
        mystr = myfile.read()
        tmppath = re.findall('<project path="(.+)"\s+name="{0}"'.format(PROJECT), mystr)
        if len(tmppath) == 1:
            mypath = tmppath[0]
            return mypath
            
        xml_list = re.findall(r'<include name="(.+)"/>', mystr)
        mypath = ''
        for next_xml in xml_list:
            with open(REPO_DIR + '/.repo/manifests/' + next_xml) as myxml:
                tmp_str = myxml.read()
                tmppath = re.findall('<project path="(.+)"\s+name="{0}"'.format(PROJECT), tmp_str)
                if len(tmppath) == 1:
                    mypath = tmppath[0]
                    #print '8888888888888============{0}'.format(mypath)
                    break
        if mypath == '':
            logger.error('can not find this git project: {0}'.format(PROJECT))
            sys.exit(1)

        return mypath


def changelog_check(changelog):
    status = True
    # 检查是不是总共5行
    #line_num = changelog.split('\n')
    #if len(line_num) != 5:
    #    logger.error('Must be 5 lines in one changelog')
    #    status = False

    first_line = changelog.split('\n')[0]
    # 检查第一行是不是'* '开头
    if not re.match(r'^\* ', first_line):
        logger.error("First line must start with '* '")
        status = False

    # 检查第一行前4个字符是不是: 星期 月 日 年, 以及格式是否符合要求
    mydate = re.findall(r'^\* (\w+ \w+ \d+ \d+)', first_line)
    try:
        datetime.datetime.strptime(mydate[0], '%a %b %d %Y')
    except Exception, e:
        logger.error('%s : %s' % (Exception, e))
        logger.error('date must be: Week Mon Date Year')
        status = False

    # 检查第一行后面的字符 修改人姓名，邮箱，以及修改后的版本号 是否填写正确
    print "xxxxxxxxxxxxxxxxxxxx" + str(re.match(r'.* \w+<.+@huawei.com> - (\w+(\.)*)*\w+-(\w+(\.)*)*\w+', first_line))
    if not re.match(r'.* \w+<.+@huawei.com> - (\w+(\.)*)*\w+-(\w+(\.)*)*\w+', first_line):
        logger.error('Author&version must be: Author<xxx@huawei.com> - version-release')
        status = False

    second_line = changelog.split('\n')[1]
    # 检查第二行是不是 '- Type:' 开头的
    if not re.match(r'^- Type:\w+', second_line):
        logger.error("Second line must start with '- Type:', and there should be no space after :.")
        status = False

    # 检查更新类型是不是属于 'bugzillas,cves,enhancement,bugfix,security,severity,recommended,new-packages'
    types = 'bugzillas,cves,enhancement,bugfix,security,severity,recommended,new-packages'.split(',')
    type_value = second_line.replace(r'- Type:', '')
    type_value_list = type_value.split(';')
    for type_tmp in type_value_list:
        if type_tmp not in types:
            logger.error("type must be one of these: {0}".format(types))
            status = False

    third_line = changelog.split('\n')[2]
    # 检查第三行是不是 '- ID:' 开头的
    if not re.match(r'^- ID:\w+', third_line):
        logger.error("Third line must start with '- ID:', and there should be no space after :. ; also, the value should not be black")
        status = False
    if type_value == 'cves':
        # 如果是cves类型的，检查ID的值是不是 CVE- 开头的
        id_value = third_line.replace(r'- ID:', '').split(',')
        for myid in id_value:
            if not re.match(r'^CVE-\w+', myid):
                logger.error("For cves or security, the ID must start with 'CVE-'")
                status = False

    fourth_line = changelog.split('\n')[3]
    # 检查第四行是不是 '- SUG:' 开头的
    if not re.match(r'^- SUG:\w+', fourth_line):
        logger.error("Third line must start with '- SUG:', and there should be no space after :. ; also, the value should not be black")
        status = False

    # 检查SUG是不是属于 'reboot,restart,NA'
    sugs = 'reboot,restart,NA'.split(',')
    sug_value = fourth_line.replace(r'- SUG:', '')
    if sug_value not in sugs:
        logger.error("type must be one of these: {0}".format(sugs))
        status = False

    fiveth_line = changelog.split('\n')[4]
    # 检查第五行是不是 '- DESC:' 开头的
    if not re.match(r'^- DESC:', fiveth_line):
        logger.error("Fiveth line must start with '- DESC:', and there should no space after :. ; also, the value should not be black")
        status = False

    if not status:
        logger.error(error_msg)
        sys.exit(1)

if __name__ == "__main__":
    project_dir = REPO_DIR + '/' + get_project_path()
    ret, out, err = shell_cmd('cd {0};git diff --name-status HEAD~1 HEAD~0'.format(project_dir))
    if ret != 0:
        print "run: %s : failed,the out is %s,the err is %s" % (COMMOND, out, err)
        sys.exit(1)
    spec_list = re.findall('M\s(.+\.spec)', out)
    if len(spec_list) == 0:
        logger.info('No spec changed, so exit as success')
        sys.exit(0)
    
    ret, out, err = shell_cmd('cd {0}; git rev-parse HEAD'.format(project_dir))
    if ret != 0:
        print "run: %s : failed,the out is %s,the err is %s" % (COMMOND, out, err)
        sys.exit(1)
    first_commitid = out
    for spec in spec_list:
        logger.info('spec is ====== {0}'.format(spec))
        ret, out, err = shell_cmd('cd {0}; git checkout {1}'.format(project_dir, first_commitid))
        if ret != 0:
            print "run: %s : failed,the out is %s,the err is %s" % (COMMOND, out, err)
            sys.exit(1)
        with open(project_dir + '/' + spec) as myfile:
            new_spec = myfile.read()

        ret, out, err = shell_cmd('cd {0}; git checkout HEAD~1'.format(project_dir))
        if ret != 0:
            print "run: %s : failed,the out is %s,the err is %s" % (COMMOND, out, err)
            sys.exit(1)

        with open(project_dir + '/' + spec) as myfile:
            old_spec = myfile.read()

        new_changelog = re.findall('.*\n%changelog\s*\n(.+)', new_spec, re.S)
        if len(new_changelog) != 1:
            logger.error('There is no changelog in spec: {0}, num ==== {1}'.format(spec, len(new_changelog)))
            sys.exit(1)
        old_changelog = re.findall('.*\n%changelog\s*\n(.+)', old_spec, re.S)
        new_log = new_changelog[0].split('\n\n*')[0]
        #logger.info(str(new_log))
        logger.info('new changelog is ================= {0}'.format(new_log))
        if len(old_changelog) != 0 and new_log in old_changelog[0]:
            logger.error('You must add a new changelog when you modify the spec')
            sys.exit(1)

        changelog_check(new_log)
